<template>
  <el-form
    ref="formRef"
    :model="form"
    :rules="rules"
    label-width="100px"
    class="demo-ruleForm"
    status-icon
  >
    <el-form-item label="包材编码" prop="materialCode">
      <el-select
        v-model="form.materialCode"
        placeholder="请选择包材编码"
        style="width: 100%"
        filterable
        :loading="loading"
        :disabled="loading"
        @change="handleMaterialChange"
      >
        <el-option 
          v-for="item in materialOptions" 
          :key="item.code"
          :label="getOptionLabel(item)"
          :value="item.code"
        />
      </el-select>
    </el-form-item>

    <el-form-item v-if="storageType === 'I'" label="入库单号" prop="storageNumber">
      <el-input v-model="form.storageNumber" />
    </el-form-item>

    <el-form-item label="数量" prop="quantity">
      <el-input-number 
        v-model="form.quantity" 
        :min="1" 
        :max="storageType === 'O' ? (selectedStock || 999999) : undefined"
        style="width: 100%" 
        :precision="0"
        @change="handleQuantityChange"
      />
      <div class="stock-info" v-if="storageType === 'O' && selectedStock > 0">
        当前库存: {{ selectedStock }}
      </div>
    </el-form-item>

    <el-form-item label="备注" prop="remark">
      <el-input v-model="form.remark" type="textarea" :rows="3" />
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, reactive, defineProps, defineEmits, watch } from 'vue'
import type { FormInstance, FormRules } from 'element-plus'

interface MaterialOption {
  code: string;
  type: string;
  description: string;
  currentStock: number;
}

const props = defineProps({
  storageType: {
    type: String,
    required: true,
    validator: (value: string) => ['I', 'O'].includes(value)
  },
  materialOptions: {
    type: Array as () => MaterialOption[],
    required: true
  },
  loading: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:form', 'material-change', 'quantity-change'])

const formRef = ref<FormInstance>()
const selectedStock = ref(0)

const form = reactive({
  storageNumber: '',
  materialCode: '',
  quantity: 1,
  remark: ''
})

// 监听表单变化并通知父组件
watch(form, (newVal) => {
  emit('update:form', { ...newVal })
}, { deep: true })

const rules = reactive<FormRules>({
  materialCode: [
    { required: true, message: '请选择包材', trigger: 'change' }
  ],
  storageNumber: props.storageType === 'I' ? [
    { required: true, message: '请输入入库单号', trigger: 'blur' }
  ] : [],
  quantity: [
    { required: true, message: '请输入数量', trigger: 'blur' },
    { type: 'number', message: '数量必须为数字', trigger: 'blur', transform(value) { return Number(value) } },
    {
      validator: (_rule, value, callback) => {
        if (props.storageType === 'O') {
          if (!selectedStock.value) {
            callback(new Error('请先选择包材'))
          } else if (value > selectedStock.value) {
            callback(new Error(`出库数量不能大于当前库存(${selectedStock.value})`))
          } else {
            callback()
          }
        } else {
          callback()
        }
      },
      trigger: 'change'
    }
  ]
})

const getOptionLabel = (item: MaterialOption) => {
  if (props.storageType === 'O') {
    return `${item.code}-${item.type}(库存:${item.currentStock})`
  }
  return `${item.code}-${item.type}`
}

const handleMaterialChange = (code: string) => {
  const material = props.materialOptions.find((item: MaterialOption) => item.code === code)
  if (material) {
    selectedStock.value = material.currentStock
    form.quantity = 1 // 重置数量为1
    emit('material-change', material)
  }
}

const handleQuantityChange = (value: number) => {
  emit('quantity-change', value)
}

const validate = () => {
  if (!formRef.value) return Promise.reject('表单实例不存在')
  return formRef.value.validate()
}

const resetFields = () => {
  if (formRef.value) {
    formRef.value.resetFields()
    selectedStock.value = 0
  }
}

defineExpose({
  form,
  validate,
  resetFields
})
</script>

<style scoped>
.stock-info {
  font-size: 12px;
  color: #909399;
  margin-top: 4px;
}
</style> 